#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <signal.h>

#include <net/if.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <ctype.h>
#include "cJSON/cJSON.h"

void url_encode(const char *src, char *dest) {
    while (*src) {
        if (isalnum((unsigned char)*src) || *src == '-' || *src == '_' || *src == '.' || *src == '~') {
            // 允许的字符不编码
            *dest++ = *src;
        } else if (*src == ' ') {
            // 空格转换为+
            *dest++ = '+';
        } else {
            // 其他字符转换为%XX
            sprintf(dest, "%%%02X", (unsigned char)*src);
            dest += 3;
        }
        src++;
    }
    *dest = '\0'; // 字符串结束符
}
int main(int argc, char const *argv[])
{
    // 1，获得指定服务器的IP
    struct hostent *p;
    p = gethostbyname("ali-weather.showapi.com");
    printf("服务器IP：%s\n", inet_ntoa(*(struct in_addr*)((p->h_addr_list)[0])));

    // 2，创建TCP并成功连接
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr;
    socklen_t len = sizeof(addr);
    bzero(&addr, len);
    addr.sin_family = AF_INET;
    addr.sin_addr = *(struct in_addr*)((p->h_addr_list)[0]);
    addr.sin_port = htons(80);
    if(connect(sockfd, (struct sockaddr*)&addr, len) == 0)
        printf("连接成功\n");


    // 3，按服务端规定，发送HTTP请求报文
    char *http_request();
    char *s = http_request();
    write(sockfd, s, strlen(s));

    // 4，接收、解析HTTP响应头部
    char *http_response = calloc(10, 1024);
    int n = 0;
    while(1)
    {
        read(sockfd, http_response+n, 1);
        n++;

        if(strstr(http_response, "\r\n\r\n"))
            break;
    }
    printf("HTTP响应头部：\n%s", http_response);

    char *json = calloc(10, 1024);
    read(sockfd, json, 1024*10);
    char *p1=strstr(json,"{");
    printf("HTTP响应报体：(JSON)\n%s", p1);

    cJSON *root = cJSON_Parse(p1);
    if(root == NULL)
        printf("json 解析失败\n");
    cJSON *showapi_res_body = cJSON_GetObjectItem(root, "showapi_res_body");
    if(showapi_res_body == NULL)
        printf("showapi_res_body 解析失败\n");
    printf("解析后的JSON数据；\n");

    cJSON *list = cJSON_GetObjectItem(showapi_res_body, "list");
    if(list==NULL)
    {
        perror("list 错误");
    }
    cJSON *item=cJSON_GetArrayItem(showapi_res_body,0);
    cJSON *cityInfo=cJSON_GetObjectItem(item,"cityInfo");
    printf("%s省 %s %s\n", cJSON_GetObjectItem(cityInfo, "c7")->valuestring, cJSON_GetObjectItem(cityInfo, "c5")->valuestring, cJSON_GetObjectItem(cityInfo, "c3")->valuestring);
    printf("经度：%f,纬度：%f\n", cJSON_GetObjectItem(cityInfo, "longitude")->valuedouble, cJSON_GetObjectItem(cityInfo, "latitude")->valuedouble);

    // cJSON *hourDataList = cJSON_GetObjectItem(showapi_res_body, "hourDataList");
    // char *area=cJSON_GetObjectItem(hourDataList, "area")->valuestring;
    // printf("地区：%s\n",area);
    return 0;
}

char *http_request()
{
    char addr[100];
    char encoded[100];
    fgets(addr,100,stdin);
    url_encode(addr, encoded);
    char *requestHead =calloc(1,1024);
    sprintf(requestHead,"GET /area-to-id?area=%s HTTP/1.1\r\n"
                        "Host: ali-weather.showapi.com\r\n"
                        "Authorization: AppCode d27ca6b6233846d28ee40d6cd690538f\r\n\r\n",encoded);
    return requestHead;
}